﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.BasicFramework;
using IPC.Communication.Core;
using IPC.Communication.Core.IMessage;
using IPC.Communication.Core.Net;
using IPC.Communication.Reflection;

namespace IPC.Communication.Profinet.LSIS
{
    public class XGKFastEnet : NetworkDeviceBase
    {
        private string CompanyID1 = "LSIS-XGT";

        private LSCpuInfo cpuInfo = LSCpuInfo.XGK;

        private byte baseNo = 0;

        private byte slotNo = 3;

        public string SetCpuType
        {
            get;
            set;
        }

        public string CpuType
        {
            get;
            private set;
        }

        public bool CpuError
        {
            get;
            private set;
        }

        public LSCpuStatus LSCpuStatus
        {
            get;
            private set;
        }

        public byte BaseNo
        {
            get
            {
                return baseNo;
            }
            set
            {
                baseNo = value;
            }
        }

        public byte SlotNo
        {
            get
            {
                return slotNo;
            }
            set
            {
                slotNo = value;
            }
        }

        public LSCpuInfo CpuInfo
        {
            get
            {
                return cpuInfo;
            }
            set
            {
                cpuInfo = value;
            }
        }

        public string CompanyID
        {
            get
            {
                return CompanyID1;
            }
            set
            {
                CompanyID1 = value;
            }
        }

        public XGKFastEnet()
        {
            base.WordLength = 2;
            IpAddress = "127.0.0.1";
            Port = 2004;
            base.ByteTransform = new RegularByteTransform();
        }

        public XGKFastEnet(string ipAddress, int port)
        {
            base.WordLength = 2;
            IpAddress = ipAddress;
            Port = port;
            base.ByteTransform = new RegularByteTransform();
        }

        public XGKFastEnet(string CpuType, string ipAddress, int port, byte slotNo)
        {
            SetCpuType = CpuType;
            base.WordLength = 2;
            IpAddress = ipAddress;
            Port = port;
            this.slotNo = slotNo;
            base.ByteTransform = new RegularByteTransform();
        }

        protected override INetMessage GetNewNetMessage()
        {
            return new LsisFastEnetMessage();
        }

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__36))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
        //{
        //    <ReadBoolAsync>d__36 stateMachine = new <ReadBoolAsync>d__36();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadCoilAsync>d__37))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<bool>> ReadCoilAsync(string address)
        //{
        //    <ReadCoilAsync>d__37 stateMachine = new <ReadCoilAsync>d__37();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadCoilAsync>d__38))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<bool[]>> ReadCoilAsync(string address, ushort length)
        //{
        //    <ReadCoilAsync>d__38 stateMachine = new <ReadCoilAsync>d__38();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadByteAsync>d__39))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<byte>> ReadByteAsync(string address)
        //{
        //    <ReadByteAsync>d__39 stateMachine = new <ReadByteAsync>d__39();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__40))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> WriteAsync(string address, byte value)
        //{
        //    <WriteAsync>d__40 stateMachine = new <WriteAsync>d__40();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteCoilAsync>d__41))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> WriteCoilAsync(string address, bool value)
        //{
        //    <WriteCoilAsync>d__41 stateMachine = new <WriteCoilAsync>d__41();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__42))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, bool value)
        //{
        //    <WriteAsync>d__42 stateMachine = new <WriteAsync>d__42();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            OperateResult<byte[]> operateResult = null;
            List<XGTAddressData> list = new List<XGTAddressData>();
            string[] array = address.Split(new string[2]
		{
			";",
			","
		}, StringSplitOptions.RemoveEmptyEntries);
            string[] array2 = array;
            foreach (string text in array2)
            {
                XGTAddressData xGTAddressData = new XGTAddressData();
                OperateResult<XGT_DataType, bool> dataTypeToAddress = GetDataTypeToAddress(text);
                if (dataTypeToAddress.Content2)
                {
                    xGTAddressData.Address = text.Substring(1);
                }
                else
                {
                    xGTAddressData.Address = text.Substring(2);
                }
                list.Add(xGTAddressData);
            }
            OperateResult<XGT_MemoryType> operateResult2 = AnalysisAddress(array[0]);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult2);
            }
            OperateResult<XGT_DataType, bool> dataTypeToAddress2 = GetDataTypeToAddress(array[0]);
            if (!dataTypeToAddress2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(dataTypeToAddress2);
            }
            operateResult = ((dataTypeToAddress2.Content1 != XGT_DataType.Continue) ? Read(dataTypeToAddress2.Content1, list, operateResult2.Content, 1) : Read(dataTypeToAddress2.Content1, list, operateResult2.Content, 1, length));
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult3);
            }
            if (list.Count > 1)
            {
                return ExtractActualDatabyte(operateResult3.Content);
            }
            return ExtractActualData(operateResult3.Content);
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            OperateResult<byte[]> operateResult = null;
            List<XGTAddressData> list = new List<XGTAddressData>();
            string[] array = address.Split(new string[2]
		{
			";",
			","
		}, StringSplitOptions.RemoveEmptyEntries);
            string[] array2 = array;
            foreach (string text in array2)
            {
                XGTAddressData xGTAddressData = new XGTAddressData();
                OperateResult<XGT_DataType, bool> dataTypeToAddress = GetDataTypeToAddress(text);
                if (dataTypeToAddress.Content2)
                {
                    xGTAddressData.Address = text.Substring(1);
                }
                else
                {
                    xGTAddressData.Address = text.Substring(2);
                }
                xGTAddressData.DataByteArray = value;
                list.Add(xGTAddressData);
            }
            OperateResult<XGT_MemoryType> operateResult2 = AnalysisAddress(address);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult2);
            }
            OperateResult<XGT_DataType, bool> dataTypeToAddress2 = GetDataTypeToAddress(address);
            if (!dataTypeToAddress2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(dataTypeToAddress2);
            }
            operateResult = ((dataTypeToAddress2.Content1 != XGT_DataType.Continue) ? Write(dataTypeToAddress2.Content1, list, operateResult2.Content, 1) : Write(dataTypeToAddress2.Content1, list, operateResult2.Content, 1, value.Length));
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult3);
            }
            return ExtractActualData(operateResult3.Content);
        }

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            OperateResult<byte[]> operateResult = null;
            List<XGTAddressData> list = new List<XGTAddressData>();
            string[] array = address.Split(new string[2]
		{
			";",
			","
		}, StringSplitOptions.RemoveEmptyEntries);
            string[] array2 = array;
            foreach (string text in array2)
            {
                XGTAddressData xGTAddressData = new XGTAddressData();
                OperateResult<XGT_DataType, bool> dataTypeToAddress = GetDataTypeToAddress(text);
                if (dataTypeToAddress.Content2)
                {
                    xGTAddressData.Address = text.Substring(1);
                }
                else
                {
                    xGTAddressData.Address = text.Substring(2);
                }
                list.Add(xGTAddressData);
            }
            OperateResult<XGT_MemoryType> operateResult2 = AnalysisAddress(array[0]);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult2);
            }
            OperateResult<XGT_DataType, bool> dataTypeToAddress2 = GetDataTypeToAddress(array[0]);
            if (!dataTypeToAddress2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(dataTypeToAddress2);
            }
            operateResult = ((dataTypeToAddress2.Content1 != XGT_DataType.Continue) ? Read(dataTypeToAddress2.Content1, list, operateResult2.Content, 1) : Read(dataTypeToAddress2.Content1, list, operateResult2.Content, 1, length));
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult3);
            }
            if (list.Count > 1)
            {
                OperateResult<bool[]> operateResult4 = ExtractActualDataBool(operateResult3.Content);
                if (!operateResult4.IsSuccess)
                {
                    return OperateResult.CreateFailedResult<bool[]>(operateResult4);
                }
                return OperateResult.CreateSuccessResult(operateResult4.Content);
            }
            OperateResult<byte[]> operateResult5 = ExtractActualData(operateResult3.Content);
            if (!operateResult5.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult5);
            }
            return OperateResult.CreateSuccessResult(SoftBasic.ByteToBoolArray(operateResult5.Content));
        }

        public OperateResult<bool> ReadCoil(string address)
        {
            return ReadBool(address);
        }

        public OperateResult<bool[]> ReadCoil(string address, ushort length)
        {
            return ReadBool(address, length);
        }

        [HslMqttApi("ReadByte", "")]
        public OperateResult<byte> ReadByte(string address)
        {
            return ByteTransformHelper.GetResultFromArray(Read(address, 1));
        }

        [HslMqttApi("WriteByte", "")]
        public OperateResult Write(string address, byte value)
        {
            return Write(address, new byte[1]
		{
			value
		});
        }

        public OperateResult WriteCoil(string address, bool value)
        {
            return Write(address, new byte[2]
		{
			(byte)(value ? 1 : 0),
			0
		});
        }

        [HslMqttApi("WriteBool", "")]
        public override OperateResult Write(string address, bool value)
        {
            return WriteCoil(address, value);
        }

        public OperateResult<byte[]> Read(XGT_DataType pDataType, List<XGTAddressData> pAddress, XGT_MemoryType pMemtype, int pInvokeID, int pDataCount = 0)
        {
            if (pAddress.Count > 16)
            {
                return new OperateResult<byte[]>("You cannot read more than 16 pieces.");
            }
            try
            {
                byte[] array = CreateReadDataFormat(XGT_Request_Func.Read, pDataType, pAddress, pMemtype, pDataCount);
                byte[] array2 = CreateHeader(pInvokeID, array.Length);
                byte[] header = new byte[array2.Length + array.Length];
                int idx = 0;
                AddByte(array2, ref idx, ref header);
                AddByte(array, ref idx, ref header);
                return OperateResult.CreateSuccessResult(header);
            }
            catch (Exception ex)
            {
                return new OperateResult<byte[]>("ERROR:" + ex.Message.ToString());
            }
        }

        public OperateResult<byte[]> Write(XGT_DataType pDataType, List<XGTAddressData> pAddressList, XGT_MemoryType pMemtype, int pInvokeID, int pDataCount = 0)
        {
            try
            {
                byte[] array = CreateWriteDataFormat(XGT_Request_Func.Write, pDataType, pAddressList, pMemtype, pDataCount);
                byte[] array2 = CreateHeader(pInvokeID, array.Length);
                byte[] header = new byte[array2.Length + array.Length];
                int idx = 0;
                AddByte(array2, ref idx, ref header);
                AddByte(array, ref idx, ref header);
                return OperateResult.CreateSuccessResult(header);
            }
            catch (Exception ex)
            {
                return new OperateResult<byte[]>("ERROR:" + ex.Message.ToString());
            }
        }

        public byte[] CreateHeader(int pInvokeID, int pDataByteLenth)
        {
            byte[] bytes = Encoding.ASCII.GetBytes(CompanyID);
            byte[] bytes2 = BitConverter.GetBytes((short)0);
            byte[] bytes3 = BitConverter.GetBytes((short)0);
            byte[] array = new byte[1];
            switch (cpuInfo)
            {
                case LSCpuInfo.XGK:
                    array[0] = 160;
                    break;
                case LSCpuInfo.XGI:
                    array[0] = 164;
                    break;
                case LSCpuInfo.XGR:
                    array[0] = 168;
                    break;
                case LSCpuInfo.XGB_MK:
                    array[0] = 176;
                    break;
                case LSCpuInfo.XGB_IEC:
                    array[0] = 180;
                    break;
            }
            byte[] array2 = new byte[1]
		{
			51
		};
            byte[] bytes4 = BitConverter.GetBytes((short)pInvokeID);
            byte[] bytes5 = BitConverter.GetBytes((short)pDataByteLenth);
            byte[] array3 = new byte[1]
		{
			(byte)(baseNo * 16 + slotNo)
		};
            byte[] array4 = new byte[1]
		{
			0
		};
            int num = bytes.Length + bytes2.Length + bytes3.Length + array.Length + array2.Length + bytes4.Length + bytes5.Length + array3.Length + array4.Length;
            byte[] header = new byte[num];
            int idx = 0;
            AddByte(bytes, ref idx, ref header);
            AddByte(bytes2, ref idx, ref header);
            AddByte(bytes3, ref idx, ref header);
            AddByte(array, ref idx, ref header);
            AddByte(array2, ref idx, ref header);
            AddByte(bytes4, ref idx, ref header);
            AddByte(bytes5, ref idx, ref header);
            AddByte(array3, ref idx, ref header);
            AddByte(array4, ref idx, ref header);
            return header;
        }

        private byte[] CreateReadDataFormat(XGT_Request_Func emFunc, XGT_DataType emDatatype, List<XGTAddressData> pAddressList, XGT_MemoryType emMemtype, int pDataCount)
        {
            List<XGTAddressData> list = new List<XGTAddressData>();
            int num = 0;
            byte[] bytes = BitConverter.GetBytes((short)emFunc);
            byte[] bytes2 = BitConverter.GetBytes((short)emDatatype);
            byte[] bytes3 = BitConverter.GetBytes((short)0);
            byte[] bytes4 = BitConverter.GetBytes((short)pAddressList.Count);
            num = bytes.Length + bytes2.Length + bytes3.Length + bytes4.Length;
            foreach (XGTAddressData pAddress in pAddressList)
            {
                string addressString = CreateValueName(emDatatype, emMemtype, pAddress.Address);
                XGTAddressData xGTAddressData = new XGTAddressData();
                xGTAddressData.AddressString = addressString;
                list.Add(xGTAddressData);
                num += xGTAddressData.AddressByteArray.Length + xGTAddressData.LengthByteArray.Length;
            }
            if (XGT_DataType.Continue == emDatatype && XGT_Request_Func.Read == emFunc)
            {
                num += 2;
            }
            byte[] header = new byte[num];
            int idx = 0;
            AddByte(bytes, ref idx, ref header);
            AddByte(bytes2, ref idx, ref header);
            AddByte(bytes3, ref idx, ref header);
            AddByte(bytes4, ref idx, ref header);
            foreach (XGTAddressData item in list)
            {
                AddByte(item.LengthByteArray, ref idx, ref header);
                AddByte(item.AddressByteArray, ref idx, ref header);
            }
            if (XGT_DataType.Continue == emDatatype)
            {
                byte[] bytes5 = BitConverter.GetBytes((short)pDataCount);
                AddByte(bytes5, ref idx, ref header);
            }
            return header;
        }

        private byte[] CreateWriteDataFormat(XGT_Request_Func emFunc, XGT_DataType emDatatype, List<XGTAddressData> pAddressList, XGT_MemoryType emMemtype, int pDataCount)
        {
            int num = 0;
            byte[] bytes = BitConverter.GetBytes((short)emFunc);
            byte[] bytes2 = BitConverter.GetBytes((short)emDatatype);
            byte[] bytes3 = BitConverter.GetBytes((short)0);
            byte[] bytes4 = BitConverter.GetBytes((short)pAddressList.Count);
            num = bytes.Length + bytes2.Length + bytes3.Length + bytes4.Length;
            List<XGTAddressData> list = new List<XGTAddressData>();
            foreach (XGTAddressData pAddress in pAddressList)
            {
                string text2 = pAddress.AddressString = CreateValueName(emDatatype, emMemtype, pAddress.Address);
                int num2 = 0;
                num2 = pAddress.DataByteArray.Length;
                num += pAddress.AddressByteArray.Length + pAddress.LengthByteArray.Length + 2 + num2;
                list.Add(pAddress);
            }
            if (XGT_DataType.Continue == emDatatype && XGT_Request_Func.Read == emFunc)
            {
                num += 2;
            }
            byte[] header = new byte[num];
            int idx = 0;
            AddByte(bytes, ref idx, ref header);
            AddByte(bytes2, ref idx, ref header);
            AddByte(bytes3, ref idx, ref header);
            AddByte(bytes4, ref idx, ref header);
            foreach (XGTAddressData item in list)
            {
                AddByte(item.LengthByteArray, ref idx, ref header);
                AddByte(item.AddressByteArray, ref idx, ref header);
            }
            foreach (XGTAddressData item2 in list)
            {
                byte[] bytes5 = BitConverter.GetBytes((short)item2.DataByteArray.Length);
                AddByte(bytes5, ref idx, ref header);
                AddByte(item2.DataByteArray, ref idx, ref header);
            }
            return header;
        }

        public string CreateValueName(XGT_DataType dataType, XGT_MemoryType memType, string pAddress)
        {
            string empty = string.Empty;
            string memTypeChar = GetMemTypeChar(memType);
            string typeChar = GetTypeChar(dataType);
            if (dataType == XGT_DataType.Continue)
            {
                pAddress = (Convert.ToInt32(pAddress) * 2).ToString();
            }
            if (dataType == XGT_DataType.Bit)
            {
                int num = 0;
                string value = pAddress.Substring(0, pAddress.Length - 1);
                string value2 = pAddress.Substring(pAddress.Length - 1);
                num = Convert.ToInt32(value2, 16);
                pAddress = ((!string.IsNullOrEmpty(value)) ? (Convert.ToInt32(value) * 16 + num).ToString() : num.ToString());
            }
            return "%" + memTypeChar + typeChar + pAddress;
        }

        private string GetTypeChar(XGT_DataType type)
        {
            string empty = string.Empty;
            switch (type)
            {
                case XGT_DataType.Bit:
                    return "X";
                case XGT_DataType.Byte:
                    return "B";
                case XGT_DataType.Word:
                    return "W";
                case XGT_DataType.DWord:
                    return "D";
                case XGT_DataType.LWord:
                    return "L";
                case XGT_DataType.Continue:
                    return "B";
                default:
                    return "X";
            }
        }

        private string GetMemTypeChar(XGT_MemoryType type)
        {
            string result = string.Empty;
            switch (type)
            {
                case XGT_MemoryType.IO:
                    result = "P";
                    break;
                case XGT_MemoryType.SubRelay:
                    result = "M";
                    break;
                case XGT_MemoryType.LinkRelay:
                    result = "L";
                    break;
                case XGT_MemoryType.KeepRelay:
                    result = "K";
                    break;
                case XGT_MemoryType.EtcRelay:
                    result = "F";
                    break;
                case XGT_MemoryType.Timer:
                    result = "T";
                    break;
                case XGT_MemoryType.DataRegister:
                    result = "D";
                    break;
                case XGT_MemoryType.Counter:
                    result = "C";
                    break;
                case XGT_MemoryType.ComDataRegister:
                    result = "N";
                    break;
                case XGT_MemoryType.FileDataRegister:
                    result = "R";
                    break;
                case XGT_MemoryType.StepRelay:
                    result = "S";
                    break;
                case XGT_MemoryType.SpecialRegister:
                    result = "U";
                    break;
            }
            return result;
        }

        private byte[] AddByte(byte[] item, ref int idx, ref byte[] header)
        {
            Array.Copy(item, 0, header, idx, item.Length);
            idx += item.Length;
            return header;
        }

        public static OperateResult<XGT_MemoryType> AnalysisAddress(string address)
        {
            XGT_MemoryType value = XGT_MemoryType.IO;
            try
            {
                char[] array = new char[15]
			{
				'P',
				'M',
				'L',
				'K',
				'F',
				'T',
				'C',
				'D',
				'S',
				'Q',
				'I',
				'N',
				'U',
				'Z',
				'R'
			};
                bool flag = false;
                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i] == address[0])
                    {
                        switch (address[0])
                        {
                            case 'P':
                                value = XGT_MemoryType.IO;
                                break;
                            case 'M':
                                value = XGT_MemoryType.SubRelay;
                                break;
                            case 'L':
                                value = XGT_MemoryType.LinkRelay;
                                break;
                            case 'K':
                                value = XGT_MemoryType.KeepRelay;
                                break;
                            case 'F':
                                value = XGT_MemoryType.EtcRelay;
                                break;
                            case 'T':
                                value = XGT_MemoryType.Timer;
                                break;
                            case 'C':
                                value = XGT_MemoryType.Counter;
                                break;
                            case 'D':
                                value = XGT_MemoryType.DataRegister;
                                break;
                            case 'N':
                                value = XGT_MemoryType.ComDataRegister;
                                break;
                            case 'R':
                                value = XGT_MemoryType.FileDataRegister;
                                break;
                            case 'S':
                                value = XGT_MemoryType.StepRelay;
                                break;
                            case 'U':
                                value = XGT_MemoryType.SpecialRegister;
                                break;
                        }
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    throw new Exception(StringResources.Language.NotSupportedDataType);
                }
            }
            catch (Exception ex)
            {
                return new OperateResult<XGT_MemoryType>(ex.Message);
            }
            return OperateResult.CreateSuccessResult(value);
        }

        public static OperateResult<XGT_DataType, bool> GetDataTypeToAddress(string address)
        {
            XGT_DataType value = XGT_DataType.Bit;
            bool value2 = false;
            try
            {
                char[] array = new char[15]
			{
				'P',
				'M',
				'L',
				'K',
				'F',
				'T',
				'C',
				'D',
				'S',
				'Q',
				'I',
				'N',
				'U',
				'Z',
				'R'
			};
                bool flag = false;
                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i] == address[0])
                    {
                        switch (address[1])
                        {
                            case 'X':
                                value = XGT_DataType.Bit;
                                break;
                            case 'W':
                                value = XGT_DataType.Word;
                                break;
                            case 'D':
                                value = XGT_DataType.DWord;
                                break;
                            case 'L':
                                value = XGT_DataType.LWord;
                                break;
                            case 'B':
                                value = XGT_DataType.Byte;
                                break;
                            case 'C':
                                value = XGT_DataType.Continue;
                                break;
                            default:
                                value2 = true;
                                value = XGT_DataType.Continue;
                                break;
                        }
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    throw new Exception(StringResources.Language.NotSupportedDataType);
                }
            }
            catch (Exception ex)
            {
                return new OperateResult<XGT_DataType, bool>(ex.Message);
            }
            return OperateResult.CreateSuccessResult(value, value2);
        }

        public OperateResult<byte[]> ExtractActualData(byte[] response)
        {
            OperateResult<bool> cpuTypeToPLC = GetCpuTypeToPLC(response);
            if (!cpuTypeToPLC.IsSuccess)
            {
                return new OperateResult<byte[]>(cpuTypeToPLC.Message);
            }
            if (response[20] == 89)
            {
                return OperateResult.CreateSuccessResult(new byte[0]);
            }
            if (response[20] == 85)
            {
                try
                {
                    ushort num = BitConverter.ToUInt16(response, 30);
                    byte[] array = new byte[num];
                    Array.Copy(response, 32, array, 0, num);
                    return OperateResult.CreateSuccessResult(array);
                }
                catch (Exception ex)
                {
                    return new OperateResult<byte[]>(ex.Message);
                }
            }
            return new OperateResult<byte[]>(StringResources.Language.NotSupportedFunction);
        }

        public OperateResult<bool> GetCpuTypeToPLC(byte[] response)
        {
            try
            {
                if (response.Length < 20)
                {
                    return new OperateResult<bool>("Length is less than 20:" + SoftBasic.ByteToHexString(response));
                }
                ushort num = BitConverter.ToUInt16(response, 10);
                BitArray bitArray = new BitArray(BitConverter.GetBytes(num));
                int num2 = (int)num % 32;
                switch ((int)num % 32)
                {
                    case 1:
                        CpuType = "XGK/R-CPUH";
                        break;
                    case 2:
                        CpuType = "XGK-CPUS";
                        break;
                    case 4:
                        CpuType = "XGK-CPUE";
                        break;
                    case 5:
                        CpuType = "XGK/R-CPUH";
                        break;
                    case 6:
                        CpuType = "XGB/XBCU";
                        break;
                }
                CpuError = bitArray[7];
                if (bitArray[8])
                {
                    LSCpuStatus = LSCpuStatus.RUN;
                }
                if (bitArray[9])
                {
                    LSCpuStatus = LSCpuStatus.STOP;
                }
                if (bitArray[10])
                {
                    LSCpuStatus = LSCpuStatus.ERROR;
                }
                if (bitArray[11])
                {
                    LSCpuStatus = LSCpuStatus.DEBUG;
                }
                if (response.Length < 28)
                {
                    return new OperateResult<bool>("Length is less than 28:" + SoftBasic.ByteToHexString(response));
                }
                ushort num3 = BitConverter.ToUInt16(response, 26);
                if (num3 > 0)
                {
                    return new OperateResult<bool>(response[28], "Error:" + GetErrorDesciption(response[28]));
                }
            }
            catch (Exception ex)
            {
                return new OperateResult<bool>(ex.Message);
            }
            return OperateResult.CreateSuccessResult(value: true);
        }

        public OperateResult<bool[]> ExtractActualDataBool(byte[] response)
        {
            OperateResult<bool> cpuTypeToPLC = GetCpuTypeToPLC(response);
            if (!cpuTypeToPLC.IsSuccess)
            {
                return new OperateResult<bool[]>(cpuTypeToPLC.Message);
            }
            if (response[20] == 89)
            {
                return OperateResult.CreateSuccessResult(new bool[0]);
            }
            if (response[20] == 85)
            {
                int num = 28;
                byte[] array = new byte[2];
                byte[] array2 = new byte[2];
                byte[] array3 = new byte[2];
                Array.Copy(response, num, array, 0, 2);
                int num2 = BitConverter.ToInt16(array, 0);
                List<bool> list = new List<bool>();
                num += 2;
                try
                {
                    for (int i = 0; i < num2; i++)
                    {
                        Array.Copy(response, num, array2, 0, 2);
                        int num3 = BitConverter.ToInt16(array2, 0);
                        num += 2;
                        array3 = new byte[num3];
                        Array.Copy(response, num, array3, 0, num3);
                        num += num3;
                        list.Add(BitConverter.ToBoolean(array3, 0));
                    }
                    return OperateResult.CreateSuccessResult(list.ToArray());
                }
                catch (Exception ex)
                {
                    return new OperateResult<bool[]>(ex.Message);
                }
            }
            return new OperateResult<bool[]>(StringResources.Language.NotSupportedFunction);
        }

        public OperateResult<byte[]> ExtractActualDatabyte(byte[] response)
        {
            OperateResult<bool> cpuTypeToPLC = GetCpuTypeToPLC(response);
            if (!cpuTypeToPLC.IsSuccess)
            {
                return new OperateResult<byte[]>(cpuTypeToPLC.Message);
            }
            if (response[20] == 89)
            {
                return OperateResult.CreateSuccessResult(new byte[0]);
            }
            if (response[20] == 85)
            {
                int num = 28;
                byte[] array = new byte[2];
                byte[] array2 = new byte[2];
                byte[] array3 = new byte[2];
                Array.Copy(response, num, array, 0, 2);
                int num2 = BitConverter.ToInt16(array, 0);
                List<byte> list = new List<byte>();
                num += 2;
                try
                {
                    for (int i = 0; i < num2; i++)
                    {
                        Array.Copy(response, num, array2, 0, 2);
                        int num3 = BitConverter.ToInt16(array2, 0);
                        num += 2;
                        Array.Copy(response, num, array3, 0, num3);
                        num += num3;
                        list.AddRange(array3);
                    }
                    return OperateResult.CreateSuccessResult(list.ToArray());
                }
                catch (Exception ex)
                {
                    return new OperateResult<byte[]>(ex.Message);
                }
            }
            return new OperateResult<byte[]>(StringResources.Language.NotSupportedFunction);
        }

        public static string GetErrorDesciption(byte code)
        {
            switch (code)
            {
                case 0:
                    return "Normal";
                case 1:
                    return "Physical layer error (TX, RX unavailable)";
                case 3:
                    return "There is no identifier of Function Block to receive in communication channel";
                case 4:
                    return "Mismatch of data type";
                case 5:
                    return "Reset is received from partner station";
                case 6:
                    return "Communication instruction of partner station is not ready status";
                case 7:
                    return "Device status of remote station is not desirable status";
                case 8:
                    return "Access to some target is not available";
                case 9:
                    return "Can’ t deal with communication instruction of partner station by too many reception";
                case 10:
                    return "Time Out error";
                case 11:
                    return "Structure error";
                case 12:
                    return "Abort";
                case 13:
                    return "Reject(local/remote)";
                case 14:
                    return "Communication channel establishment error (Connect/Disconnect)";
                case 15:
                    return "High speed communication and connection service error";
                case 33:
                    return "Can’t find variable identifier";
                case 34:
                    return "Address error";
                case 50:
                    return "Response error";
                case 113:
                    return "Object Access Unsupported";
                case 187:
                    return "Unknown error code (communication code of other company) is received";
                default:
                    return "Unknown error";
            }
        }

        public override string ToString()
        {
            return String.Format("XGkFastEnet[{0}:{1}]", IpAddress, Port);
        }
    }
}